﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
using T.FAS.Action.Dev.Entity;
using T.FAS.Action.MetaData.Entity;
using T.FAS.Base.Dao;
using Teld.Core.DAC.Service;
using Teld.Core.DataAccessEx.Core;
using Teld.CoreEx.Runtime.Common.Utility;

namespace T.FAS.Action.Dev.Dao
{
    public class ActionDevELBDao : DaoService<ActionMetaDataView>, IActionDevDao
    {
        public const string MetaDataID = "ActionMetaData";
        public const string MetaDataName = "Action元数据";
        public override string TableName => "FAS_ActionMetaData";
        public override string IDColumnName => "ID";
        public override List<string> ExceptColumnName
            => DaoUtil.GetExceptionColumn<ActionMetaData>(
                new List<string>
                {
                    "MetaDataID",
                    "MetaDataCode",
                    "MetaDataName"
                }
            );

        public override ActionMetaDataView ConvertToObject(Dictionary<string, PropertyInfo> columns, DataRow row)
        {
            if (columns.ContainsKey("ActionType"))
                columns.Remove("ActionType");
            if (columns.ContainsKey("ReturnValueType"))
                columns.Remove("ReturnValueType");

            var data = base.ConvertToObject(columns, row);

            data.ActionType = (ActionType)Enum.Parse(typeof(ActionType), Convert.ToString(row["ActionType"]));
            data.ReturnValueType = (ReturnValueType)Enum.Parse(typeof(ReturnValueType), Convert.ToString(row["ReturnValueType"]));

            return data;
        }

        public override Dictionary<string, object> GetDataMapping(ActionMetaDataView data)
        {
            var mapping = base.GetDataMapping(data);
            mapping.Remove("ActionType");
            mapping.Add("ActionType", (int)data.ActionType);

            mapping.Remove("ReturnValueType");
            mapping.Add("ReturnValueType", (int)data.ReturnValueType);

            return mapping;
        }
        public ActionDevELBDao() : base()
        {
            DBName = "TeldFAS";
        }
        public override Dictionary<string, PropertyInfo> GetColumns()
        {
            return DaoServiceExtension.GetAllColumns<ActionMetaData>(base.GetColumns());
        }

        /// <summary>
        /// 根据条件查询获取数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public List<ActionMetaDataView> GetActionMetaDataViewsByFilter(Dictionary<string, string> filter)
        {
            var rows = Convert.ToInt16(filter["rows"]);
            var offset = Convert.ToInt16(filter["offset"]);

            var pageSql = "";
            if (!rows.Equals(0))
            {
                pageSql = $" limit {rows} offset {offset}";
            }
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
            var sql = @"SELECT AM.ID,AM.Code,AM.Name,AM.ReturnValueType,AM.Description,AM.IsClientAction,AM.ActionType,AM.RelatedMetaDataID FROM FAS_ACTIONMETADATA AM WHERE 1=1 ";

            if (filter.ContainsKey("AppID") && filter.ContainsKey("ModuleID"))
            {
                paramsList.Add(DB.MakeInParam("@ModuleID", TeldDbDataType.VarChar, filter["ModuleID"]));
                paramsList.Add(DB.MakeInParam("@AppID", TeldDbDataType.VarChar, filter["AppID"]));
                sql += " and EXISTS (SELECT 1 FROM FAS_ACLDETAIL DETAIL LEFT JOIN FAS_ACLDEFINE DEFINE ON DEFINE.ID = DETAIL.ACLDEFINEID WHERE DEFINE.ACLMETADATATYPE = 0 AND DEFINE.ACLMETADATAID = AM.ID AND ((DETAIL.ISALLAPP = 1 AND DETAIL.ISALLMODULE = 1) OR (DETAIL.ISALLAPP = 1 AND DETAIL.ISALLMODULE = 0 AND MODULEID=@ModuleID) OR (DETAIL.ISALLAPP = 0 AND DETAIL.APPID = @AppID AND DETAIL.ISALLMODULE = 1) OR (DETAIL.ISALLAPP = 0 AND DETAIL.APPID = @AppID AND DETAIL.ISALLMODULE = 0 AND DETAIL.MODULEID=@ModuleID)))";
            }

            if (filter.ContainsKey("ID"))
            {
                sql += $" and AM.ID like @ID";
                paramsList.Add(DB.MakeInParam("@ID", TeldDbDataType.VarChar, "%"+filter["ID"] +"%"));
            }
            if (filter.ContainsKey("Code"))
            {
                sql += $" and AM.Code like @Code";
                paramsList.Add(DB.MakeInParam("@Code", TeldDbDataType.VarChar, "%" + filter["Code"]+ "%"));
            }
            if (filter.ContainsKey("Name"))
            {
                sql += $" and AM.Name like @Name";
                paramsList.Add(DB.MakeInParam("@Name", TeldDbDataType.VarChar, "%" + filter["Name"]+ "%"));
            }
            if (filter.ContainsKey("conditions"))
            {
                sql+= $" and (AM.Name like @conditions or AM.Code like @conditions)";
                paramsList.Add(DB.MakeInParam("@conditions",TeldDbDataType.VarChar, "%" + filter["conditions"]+ "%"));
            }
            if (filter.ContainsKey("ReturnValueType"))
            {
                sql += " and AM.ReturnValueType =@ReturnValueType ";
                paramsList.Add(DB.MakeInParam("@ReturnValueType",TeldDbDataType.VarChar,filter["ReturnValueType"]));
            }
            bool isUserDefineSort = false;
            if (filter.ContainsKey("Sys_SortFilter"))
            {
                var sortFilter = filter["Sys_SortFilter"];
                if (!string.IsNullOrEmpty(sortFilter))
                {
                    var sortFilterDic = JsonConvert.DeserializeObject<Dictionary<string, string>>(sortFilter);
                    if (sortFilterDic != null && sortFilterDic.Count > 0)
                    {
                        string sortSql = "";
                        int index = 0;
                        sortFilterDic.ForEach((k, v) =>
                        {
                            if (!string.IsNullOrEmpty(v))
                            {
                                if (index == 0)
                                    sortSql += $"AM.{k} {(v.Equals("desc", StringComparison.OrdinalIgnoreCase) ? "Desc" : "Asc")}";
                                else
                                    sortSql += $" ,AM.{k} {(v.Equals("desc", StringComparison.OrdinalIgnoreCase) ? "Desc" : "Asc")}";
                            }
                            index++;
                        });
                        if (!string.IsNullOrEmpty(sortSql))
                        {
                            isUserDefineSort = true;
                            sql += $" Order by {sortSql} {pageSql}";
                        }
                    }
                }
            }
            if(!isUserDefineSort)
            { 
                sql += $" Order by AM.LastModifyTime {pageSql}";
            }
            var dataResult = DB.ExecuteDataSet(sql,paramsList.ToArray());
            return DataResultConvert.ConvertToActionMetaDataView(dataResult);
        }
        /// <summary>
        /// 获取查询总条数
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public int GetActionMetaDataViewsCountByFilter(Dictionary<string, string> filter)
        {
            List<IDbDataParameter> paramsList = new List<IDbDataParameter>();

            var sql = "SELECT COUNT(1) FROM FAS_ActionMetaData AM WHERE 1=1 ";

            if (filter.ContainsKey("AppID") && filter.ContainsKey("ModuleID"))
            {
                paramsList.Add(DB.MakeInParam("@ModuleID", TeldDbDataType.VarChar, filter["ModuleID"]));
                paramsList.Add(DB.MakeInParam("@AppID", TeldDbDataType.VarChar, filter["AppID"]));
                sql += " and EXISTS (SELECT 1 FROM FAS_ACLDETAIL DETAIL LEFT JOIN FAS_ACLDEFINE DEFINE ON DEFINE.ID = DETAIL.ACLDEFINEID WHERE DEFINE.ACLMETADATATYPE = 0 AND DEFINE.ACLMETADATAID = AM.ID AND ((DETAIL.ISALLAPP = 1 AND DETAIL.ISALLMODULE = 1) OR (DETAIL.ISALLAPP = 1 AND DETAIL.ISALLMODULE = 0 AND MODULEID=@ModuleID) OR (DETAIL.ISALLAPP = 0 AND DETAIL.APPID = @AppID AND DETAIL.ISALLMODULE = 1) OR (DETAIL.ISALLAPP = 0 AND DETAIL.APPID = @AppID AND DETAIL.ISALLMODULE = 0 AND DETAIL.MODULEID=@ModuleID)))";
            }

            if (filter.ContainsKey("ID"))
            {
                sql += $" and AM.ID like @ID";
                paramsList.Add(DB.MakeInParam("@ID", TeldDbDataType.VarChar, "%" + filter["ID"] +"%"));
            }
            if (filter.ContainsKey("Code"))
            {
                sql += " and AM.Code like @Code";
                paramsList.Add(DB.MakeInParam("@Code",TeldDbDataType.VarChar, "%" + filter["Code"]+"%"));
            }
            if (filter.ContainsKey("Name"))
            {
                sql += " and AM.Name like @Name";
                paramsList.Add(DB.MakeInParam("@Name",TeldDbDataType.VarChar, "%" + filter["Name"]+"%"));
            }
            if (filter.ContainsKey("conditions"))
            {
                sql += $" and (AM.Name like @conditions or AM.Code like @conditions)";
                paramsList.Add(DB.MakeInParam("@conditions", TeldDbDataType.VarChar, "%"+filter["conditions"]+"%"));
            }
            if (filter.ContainsKey("ReturnValueType"))
            {
                sql += " and AM.ReturnValueType = @ReturnValueType ";
                paramsList.Add(DB.MakeInParam("@ReturnValueType", TeldDbDataType.VarChar, filter["ReturnValueType"]));
            }
            var count = DB.ExecuteScalar(sql, paramsList.ToArray());
            return count == null ? 0 : Convert.ToInt16(count);
        }

        public List<ActionParamsView> GetActionMetaDataMethodParamViewByActionId(string id)
        {
            var paramList = new List<IDbDataParameter>();
            var sql = "SELECT Param.ID,Param.Code,Param.Name,Param.SortOrder,Param.ParamType,Param.ParamSourceType,Param.SourceID,Param.SourceName,Param.ParamAssembly,Param.ParamValueType,Param.DefaultValue,Param.Description,Param.Ext1,Param.Ext2,Param.Ext3,Param.Creator,Param.CreateTime,Param.LastModifier,Param.LastModifyTime From fas_actionmetadatamethodparam Param where Param.ActionMetaDataID =@ID";
            paramList.Add(DB.MakeInParam("@ID",TeldDbDataType.VarChar,id));
            var dataResult = DB.ExecuteDataSet(sql, paramList.ToArray());
            return DataResultConvert.ConvertToActionParamsView(dataResult);
        }

        public ActionMetaDataView GetActionMetaDataViewByID(string id)
        {
            var data = base.Get(id);
            return data == null ? null : data as ActionMetaDataView;
        }
    }
}
